package com.system.manager.modules.projectLibrary.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.system.manager.common.constant.SysConstants;
import com.system.manager.common.entity.Result;
import com.system.manager.common.enums.ErrorCode;
import com.system.manager.common.exception.SysException;
import com.system.manager.modules.authorized.entity.Subject;
import com.system.manager.modules.authorized.mapper.UserMapper;
import com.system.manager.modules.projectLibrary.dto.ProjectDto;
import com.system.manager.modules.projectLibrary.entity.*;
import com.system.manager.modules.projectLibrary.enums.ProjectLibraryErrorCode;
import com.system.manager.modules.projectLibrary.exception.ProjectLibraryException;
import com.system.manager.modules.projectLibrary.mapper.DepartmentMapper;
import com.system.manager.modules.projectLibrary.mapper.EnterpriseMapper;
import com.system.manager.modules.projectLibrary.mapper.ProjectLeaderMapper;
import com.system.manager.modules.projectLibrary.mapper.ProjectMapper;
import com.system.manager.modules.projectLibrary.service.IEnterpriseService;
import com.system.manager.modules.projectLibrary.service.IProjectChangeService;
import com.system.manager.modules.projectLibrary.service.IProjectService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.system.manager.modules.projectLibrary.vo.ProjectByDepartmentVo;
import com.system.manager.utils.FileUtil;
import com.system.manager.utils.UUIDUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jisf
 * @since 2021-11-03
 */
@Service
public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> implements IProjectService {

    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    private IProjectChangeService iProjectChangeService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private IProjectService iProjectService;

    @Autowired
    private EnterpriseMapper enterpriseMapper;

    @Autowired
    private DepartmentMapper departmentMapper;

    @Autowired
    private ProjectLeaderMapper projectLeaderMapper;


    @Autowired
    private IEnterpriseService enterpriseService;

    /**
     * TODO 插入项目信息
     *
     * @param project
     */
    @Override
    public void insertProject(Project project, Subject subject) {
        //为该项目设置项目id
        String randomUUID = UUIDUtils.randomUUID();
        project.setProject_id(randomUUID);
        //查询该公司该项目的项目名是否存在
        //查询访问用户所属公司
        Integer organizationId = userMapper.selectById(subject.getId()).getOrganizationId();
        //查询项目名称是否存在
        QueryWrapper<Project> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", project.getName());
        Project selectProject = projectMapper.selectOne(queryWrapper);
        //查看该项目是否属于该公司
        if (selectProject != null) {
            Integer firm = selectProject.getFirm();
            if (organizationId.equals(firm)) {
                throw new ProjectLibraryException(ProjectLibraryErrorCode.PROJECT_NAME_ALREADY_EXIST);
            }
        }
        //将项目放入该公司名下
        project.setFirm(organizationId);
        project.setCheckAccept(0);
        //插入项目信息
        try {
            projectMapper.insert(project);
        } catch (Exception e) {
            throw new SysException();
        }

    }

    /**
     * TODO 修改项目信息
     *
     * @param project
     * @param subject
     */
    @Override
    public void updateProject(Project project, Subject subject) {

        if (project.getName() != null && project.getStartTime() != null &&
                project.getEndTime() != null) {
            //记录项目变更
            ProjectChange projectChange = new ProjectChange(project.getProject_id(), subject.getId(), new Date(), 0);
            iProjectChangeService.insertProjectChange(projectChange, project);
        }
        //修改项目信息
        try {
            projectMapper.updateById(project);
        } catch (Exception e) {
            throw new ProjectLibraryException(ProjectLibraryErrorCode.UPDATE_PROJECT_FAILURE);
        }

    }

    /**
     * TODO 管理项目负责人
     *
     * @param project
     */
    @Override
    public void manageProjectLeader(Project project) {

        //更换项目负责人或项目其他信息
        try {
            projectMapper.updateById(project);
        } catch (Exception e) {
            throw new SysException();
        }

    }


    /**
     * TODO 处理备案审核
     *
     * @param id
     * @param putOnRecords
     */
    @Override
    public String auditProject(Integer id, Integer putOnRecords) {
        if (putOnRecords != null) {
            UpdateWrapper<Project> updateWrapper = new UpdateWrapper<>();
            updateWrapper.set("put_on_records", putOnRecords).eq("id", id);
            try {
                //项目通过审核，表示已备案
                iProjectService.update(updateWrapper);
                return putOnRecords == 1 ? "已通过" : "已拒绝";
            } catch (Exception e) {
                throw new ProjectLibraryException(ProjectLibraryErrorCode.AUDIT_UPDATE_FAILURE);
            }
        }
        return "操作失败";
    }


    /**
     * TODO 按项目类型查询本公司所有项目
     *
     * @param projectType
     * @return
     */
    @Override
    public Result selectProjectByType(Integer currPage, Integer size, String projectType, String name, String startTime, String endTime, Integer department, String putOnRecords, String checkAccept, Subject subject) {
        //分页查询
        IPage<Project> projectIPage = new Page<>(currPage, size);

        //查询登录角色账号
        String userAccount = userMapper.selectById(subject.getId()).getUserAccount();

        //根据账号查询公司
        QueryWrapper<Enterprise> enterpriseQueryWrapper = new QueryWrapper<>();
        enterpriseQueryWrapper.eq("username", userAccount);
        int firm = enterpriseMapper.selectOne(enterpriseQueryWrapper).getId();

        //查询本公司下的所有项目
        QueryWrapper<Project> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("firm", firm);

        //按项目类型分类
        if (projectType != null && !projectType.equals("")) {
            switch (projectType) {
                case "内贸流通发展专项资金项目":
                    queryWrapper.eq("project_type", 1);
                    break;
                case "外经贸发展专项资金项目":
                    queryWrapper.eq("project_type", 2);
                    break;
                case "服务外包业产业发展专项资金项目":
                    queryWrapper.eq("project_type", 3);
                    break;
                case "区域服务业发展专项资金项目":
                    queryWrapper.eq("project_type", 4);
                    break;
                case "市商务委部门专项资金项目":
                    queryWrapper.eq("project_type", 5);
                    break;
                case "规划分配专项资金项目":
                    queryWrapper.eq("project_type", 6);
                    break;
                default:
                    break;
            }
        }

        //按项目名称查询
        if (name != null && !name.equals("")) {
            queryWrapper.eq("name", name);
        }

        //按启动时间删选
        if (startTime != null && !startTime.equals("")) {
            queryWrapper.ge("start_time", startTime);
        }
        //按结束时间删选
        if (endTime != null && !endTime.equals("")) {
            queryWrapper.le("end_time", endTime);
        }

        //按部门查询
        if (department != null) {
            queryWrapper.eq("department", department);
        }

        //按备案状态查询
        if (putOnRecords != null && !putOnRecords.equals("")) {
            switch (putOnRecords) {
                case "未申请":
                    queryWrapper.isNull("put_on_records");
                    break;
                case "未备案":
                    queryWrapper.eq("put_on_records", 0);
                    break;
                case "已备案":
                    queryWrapper.eq("put_on_records", 1);
                    break;
                case "未通过":
                    queryWrapper.eq("put_on_records", -1);
                    break;
            }
        }

        //按验收状态查询
        if (checkAccept != null && !checkAccept.equals("")) {
            switch (checkAccept) {
                case "未验收":
                    queryWrapper.eq("check_accept", 0);
                    break;
                case "已验收":
                    queryWrapper.eq("check_accept", 1);
                    break;
            }
        }

        queryWrapper.orderByDesc("application_time");

        page(projectIPage, queryWrapper);

        //封装数据返回给前端
        List<Project> projects = projectIPage.getRecords();
        List<ProjectDto> projectDtos = new ArrayList<>();

        for (int i = 0; i < projects.size(); i++) {
            ProjectDto projectDto = new ProjectDto();
            BeanUtils.copyProperties(projects.get(i), projectDto);
            Project project = projects.get(i);
            Integer grtFirm = project.getFirm();
            Integer getDepartment = project.getDepartment();
            Integer getPrincipal = project.getPrincipal();
            if (grtFirm != null) {
                projectDto.setFirm(enterpriseMapper.selectById(grtFirm).getName());
            }
            if (getDepartment != null) {
                projectDto.setDepartment(departmentMapper.selectById(getDepartment).getName());
            }
            if (getPrincipal != null) {
                projectDto.setPrincipal(projectLeaderMapper.selectById(getPrincipal).getName());
            }
            projectDtos.add(projectDto);
        }

        int total = (int) projectIPage.getTotal();

        return Result.ok(projectDtos, total);

    }

    /**
     * TODO 备案申请
     *
     * @param id
     */
    @Override
    public String applyPutOnRecords(Integer id) {
        Project project = new Project();
        project.setId(id);

        //获取项目的备案状态
        Project selectProject = projectMapper.selectById(id);
        //获取备案状态
        Integer putOnRecords = selectProject.getPutOnRecords();
        if(putOnRecords != null){
            if (putOnRecords == 0 || putOnRecords == 1) {
                return "已申请备案，不能重复申请";
            }
            //获取上次申报时间
            Date applicationTime = selectProject.getApplicationTime();
            if (applicationTime != null) {
                Date date = new Date();
                int time = (int) (date.getTime() - applicationTime.getTime());
                int house = time / (3600 * 1000);
                if (house < 24) {
                    int timeOut = 24 - house;
                    return "申请频繁，请" + timeOut + "小时后再申请";
                }
            }
        }
        project.setPutOnRecords(0);
        project.setApplicationTime(new Date());
        try {
            projectMapper.updateById(project);
            return "申请成功";
        } catch (Exception e) {
            throw new SysException();
        }

    }

    /**
     * TODO 删除项目
     *
     * @param id
     */
    @Override
    public String deleteProject(String id) {

        try {
            projectMapper.deleteById(id);
            return "删除成功";
        } catch (Exception e) {
            throw new SysException();
        }
    }

    /**
     * TODO 查询有人管理的项目
     *
     * @param subject
     * @return
     */
    public List<Project> selectProjectHaveProjectLeader(Subject subject) {
        Integer firm = userMapper.selectById(subject.getId()).getOrganizationId();
        QueryWrapper<Project> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("firm", firm);
        queryWrapper.isNotNull("principal");
        queryWrapper.select("id", "name");
        List<Project> projects = projectMapper.selectList(queryWrapper);
        return projects;
    }

    /**
     * TODO 根据项目id查询项目名
     *
     * @param id
     * @return
     */
    public String selectNameById(Integer id) {
        if (id != null) {
            String name = projectMapper.selectById(id).getName();
            return name;
        }
        return "";
    }

    @Override
    public String createPdf(String id) {
        // 1.查询出当前的项目内容
        Project project = getById(id);

        // 2.封装要展示的信息
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("projectName", project.getName());
        paramMap.put("startTime", project.getStartTimeString());
        paramMap.put("introduce", project.getIntroduce());
        paramMap.put("expectEffect", project.getExpectEffect());
        paramMap.put("projectType", getProjectTypeString(project.getProjectType()));
        paramMap.put("applicationTime", project.getApplicationTimeString());
        Enterprise enterprise = enterpriseService.getById(project.getFirm());
        paramMap.put("firm", enterprise.getName());
        paramMap.put("principal", project.getPrincipal());

        // 3.生成pdf文件路径
        String pdfUrl = "";
        try {
            pdfUrl = FileUtil.createPdf(SysConstants.SYS_TEMPLATE_HTML_DIR, SysConstants.SYS_TEMPLATE_HTML_NAME, paramMap);
        } catch (Exception e) {
            e.printStackTrace();
            throw new SysException(ErrorCode.PDF_IS_VALID);
        }
        return pdfUrl;
    }

    public String getProjectTypeString(Integer projectType) {

        switch (projectType) {
            case 1:
                return "内贸流通发展专项资金项目";
            case 2:
                return "外经贸发展专项资金项目";
            case 3:
                return "服务外包业产业发展专项资金项目";
            case 4:
                return "区域服务业发展专项资金项目";
            case 5:
                return "市商务委部门专项资金项目";
            case 6:
                return "规划分配专项资金项目";
            default:
                return "无";
        }

    }

    /**
     * TODO 按部门查询公司所有项目
     *
     * @param subject
     * @return
     */
    public List<ProjectByDepartmentVo> selectProjectByDepartment(Subject subject) {

        int num = 1;

        List<ProjectByDepartmentVo> list = new ArrayList<>();
        Integer firm = userMapper.selectById(subject.getId()).getOrganizationId();
        //查询所有部门
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("firm", firm);
        List<Department> departments = departmentMapper.selectList(queryWrapper);

        //根据各个部门查询项目
        for (int i = 0; i < departments.size(); i++) {
            //将部门加入返回给前端的集合
            ProjectByDepartmentVo project = new ProjectByDepartmentVo();
            BeanUtils.copyProperties(departments.get(i), project);
            //赋值sid
            project.setSid(num++);
            //赋值pid
            project.setPid(-1);
            //交换sid和id
            int temp = project.getId();
            project.setId(project.getSid());
            project.setSid(temp);
            list.add(project);
            //查询该部门下的所有项目
            int department = departments.get(i).getId();
            QueryWrapper<Project> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("department", department);
            List<Project> projects = projectMapper.selectList(queryWrapper1);
            for (int j = 0; j < projects.size(); j++) {
                //将项目加入返回给前端的集合
                ProjectByDepartmentVo project1 = new ProjectByDepartmentVo();
                BeanUtils.copyProperties(projects.get(j), project1);
                //赋值项目负责人
                Integer principal = projects.get(j).getPrincipal();
                if (principal != null) {

                    ProjectLeader projectLeader = projectLeaderMapper.selectById(principal);
                    String name = projectLeader.getName();
                    String username = projectLeader.getUsername();
                    project1.setPrincipal(name);
                    project1.setUsername(username);
                }
                //赋值sid
                project1.setSid(num++);
                //赋值pid
                project1.setPid(project.getId());
                //交换sid和id
                temp = project1.getId();
                project1.setId(project1.getSid());
                project1.setSid(temp);
                list.add(project1);
            }
        }
        return list;
    }

    /**
     * TODO 设置项目负责人
     * @param id
     * @param project
     */
    @Override
    public String setProjectLeader(Integer id, String project, Subject subject) {
        if(project == null || project.equals("")){
            return "该用户没有负责项目";
        }
        Integer organizationId = userMapper.selectById(subject.getId()).getOrganizationId();
        //修改用户角色
        //查项目原负责人
        QueryWrapper<Project> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("firm",organizationId);
        queryWrapper.eq("name",project);
        Integer principal = projectMapper.selectOne(queryWrapper).getPrincipal();
        //修改原负责人的角色为普通用户
        ProjectLeader projectLeader = new ProjectLeader();
        projectLeader.setId(principal);
        projectLeader.setRole(0);
        try {
            projectLeaderMapper.updateById(projectLeader);
        }catch (Exception e){
            throw new SysException();
        }
        //修改现负责人的角色为项目负责人
        projectLeader = new ProjectLeader();
        projectLeader.setId(id);
        projectLeader.setRole(1);
        try {
            projectLeaderMapper.updateById(projectLeader);
        }catch (Exception e){
            throw new SysException();
        }
        //设置项目负责人
        UpdateWrapper<Project> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("principal",id);
        updateWrapper.eq("firm",organizationId);
        updateWrapper.eq("name",project);
        try {
            projectMapper.update(new Project(), updateWrapper);
        }catch (Exception e){
            throw new SysException();
        }
        return "设置成功";
    }

    /**
     * TODO 分配项目
     * @param id
     * @param project
     * @return
     */
    public String setProject(Integer id,Integer project){
        ProjectLeader projectLeader = new ProjectLeader();
        projectLeader.setId(id);
        projectLeader.setProject(project);
        try {
            projectLeaderMapper.updateById(projectLeader);
            return "分配成功";
        }catch (Exception e){
            throw new SysException();
        }

    }

    /**
     * TODO 查询自己负责的项目
     * @param subject
     * @return
     */
    public ProjectDto selectOneProject(Subject subject){
        String userAccount = userMapper.selectById(subject.getId()).getUserAccount();
        QueryWrapper<ProjectLeader> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username",userAccount);
        Integer projectId = projectLeaderMapper.selectOne(queryWrapper).getProject();
        Project project = projectMapper.selectById(projectId);
        ProjectDto projectDto = new ProjectDto();
        BeanUtils.copyProperties(project,projectDto);
        Integer getFirm = project.getFirm();
        Integer getDepartment = project.getDepartment();
        Integer getPrincipal = project.getPrincipal();
        if (getFirm != null) {
            projectDto.setFirm(enterpriseMapper.selectById(getFirm).getName());
        }
        if (getDepartment != null) {
            projectDto.setDepartment(departmentMapper.selectById(getDepartment).getName());
        }
        if (getPrincipal != null) {
            projectDto.setPrincipal(projectLeaderMapper.selectById(getPrincipal).getName());
        }
        return projectDto;
    }

    /**
     * TODO 查询所有申请项目
     * @param page
     * @param size
     * @param firm
     * @param putOnRecords
     * @param projectType
     * @return
     */
    @Override
    public Result selectAllProject(Integer page, Integer size, Integer firm, String putOnRecords, String projectType, String checkAccept) {
        IPage<Project> projectIPage = new Page<>(page,size);
        QueryWrapper<Project> queryWrapper = new QueryWrapper<>();
        //根据公司查询
        if(firm != null){
            queryWrapper.eq("firm",firm);
        }
        //根据是否备案查询
        if (putOnRecords != null && !putOnRecords.equals("")) {
            switch (putOnRecords) {
                case "未申请":
                    queryWrapper.isNull("put_on_records");
                    break;
                case "未备案":
                    queryWrapper.eq("put_on_records", 0);
                    break;
                case "已备案":
                    queryWrapper.eq("put_on_records", 1);
                    break;
                case "未通过":
                    queryWrapper.eq("put_on_records", -1);
                    break;
            }
        }
        //根据验收状态查询
        if (checkAccept != null && !checkAccept.equals("")) {
            switch (checkAccept) {
                case "未验收":
                    queryWrapper.eq("check_accept", 0);
                    break;
                case "已验收":
                    queryWrapper.eq("check_accept", 1);
                    break;
            }
        }
        //根据项目类型查询
        if (projectType != null && !projectType.equals("")) {
            switch (projectType) {
                case "内贸流通发展专项资金项目":
                    queryWrapper.eq("project_type", 1);
                    break;
                case "外经贸发展专项资金项目":
                    queryWrapper.eq("project_type", 2);
                    break;
                case "服务外包业产业发展专项资金项目":
                    queryWrapper.eq("project_type", 3);
                    break;
                case "区域服务业发展专项资金项目":
                    queryWrapper.eq("project_type", 4);
                    break;
                case "市商务委部门专项资金项目":
                    queryWrapper.eq("project_type", 5);
                    break;
                case "规划分配专项资金项目":
                    queryWrapper.eq("project_type", 6);
                    break;
                default:
                    break;
            }
        }
        queryWrapper.orderByDesc("application_time");

        page(projectIPage, queryWrapper);

        //封装数据返回给前端
        List<Project> projects = projectIPage.getRecords();
        List<ProjectDto> projectDtos = new ArrayList<>();

        for (int i = 0; i < projects.size(); i++) {
            ProjectDto projectDto = new ProjectDto();
            BeanUtils.copyProperties(projects.get(i), projectDto);
            Project project = projects.get(i);
            Integer grtFirm = project.getFirm();
            Integer getDepartment = project.getDepartment();
            Integer getPrincipal = project.getPrincipal();
            if (grtFirm != null) {
                projectDto.setFirm(enterpriseMapper.selectById(grtFirm).getName());
            }
            if (getDepartment != null) {
                projectDto.setDepartment(departmentMapper.selectById(getDepartment).getName());
            }
            if (getPrincipal != null) {
                projectDto.setPrincipal(projectLeaderMapper.selectById(getPrincipal).getName());
            }
            projectDtos.add(projectDto);
        }

        int total = (int) projectIPage.getTotal();

        return Result.ok(projectDtos, total);

    }
}
